package com.dtease.agent.sync;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.Resource;

import com.dtease.agent.biz.agentstore.model.BasToolsMetaDataTable;
import com.dtease.agent.biz.agentstore.service.IBasToolsMetaDatabaseService;
import com.dtease.agent.biz.resource.dto.BasStorageDTO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.dtease.agent.core.enums.StorageTypeEnum;
import com.dtease.agent.biz.resource.service.IBasStorageService;
import com.dtease.agent.sync.extractor.HiveMetadataExtractor;
import com.dtease.agent.sync.extractor.IMetadataExtractor;
import com.dtease.agent.sync.extractor.MySqlMetadataExtractor;
import com.google.common.collect.Lists;

import lombok.extern.slf4j.Slf4j;

/**
* @description 元数据同步服务
* @author chentl
* @class MetadataSyncService
* @package com.dtease.agent.metadata.sync
* @since 2025/5/7 14:16
*/
@Slf4j
@Service
public class MetadataSyncService {

    public static final String GROUP_KEY_CONNECTOR = "::";
    private final Map<Integer, IMetadataExtractor> extractorMap = new ConcurrentHashMap<>();

    @Resource
    private IBasStorageService basStorageService;

    @Resource
    private IBasToolsMetaDatabaseService toolsMetaDataTableService;

    public MetadataSyncService(MySqlMetadataExtractor mySqlMetadataExtractor, HiveMetadataExtractor hiveMetadataExtractor) {
        extractorMap.put(StorageTypeEnum.MYSQL.getStorageType(), mySqlMetadataExtractor);
        extractorMap.put(StorageTypeEnum.HIVE.getStorageType(), hiveMetadataExtractor);
    }

    /**
     * @description 同步元数据
     * @author chentl
     * @since 14:16 2025/5/7
     **/
    public void syncMetadata() {
        log.info("开始同步元数据...");
        try {
            List<BasStorageDTO> storages = basStorageService.listByTypes(
                    Lists.newArrayList(StorageTypeEnum.MYSQL.getStorageType(), StorageTypeEnum.HIVE.getStorageType())
            );

            if(CollectionUtils.isEmpty(storages)){
                log.warn("没有需要同步的元数据");
            }

            for (BasStorageDTO storage : storages) {
                IMetadataExtractor extractor = extractorMap.get(storage.getStorageType());
                if (extractor != null) {
                    extractor.extractAndSave(storage);
                }
            }
            log.info("元数据同步完成...");
        }catch (Exception e){
            log.error("元数据同步失败", e);
        }

    }

    /**
     * @description 同步元数据标签
     * @author chentl
     * @since 14:16 2025/5/7
     **/
    public void syncMetaTags() {
        log.info("开始同步元数据标签...");
        try {
            List<BasToolsMetaDataTable> basToolsMetaDataTableList = toolsMetaDataTableService.listByTableGroup();

            if(CollectionUtils.isEmpty(basToolsMetaDataTableList)){
                log.debug("没有需要同步的元数据标签");
                return;
            }

            Map<String,String> tableTagsMap = new ConcurrentHashMap<>();
            for(BasToolsMetaDataTable basToolsMetaDataTable : basToolsMetaDataTableList){
                String tableTagsKey = basToolsMetaDataTable.getTenantId() + GROUP_KEY_CONNECTOR + basToolsMetaDataTable.getStorageId() + GROUP_KEY_CONNECTOR +
                        basToolsMetaDataTable.getDatabaseName() + GROUP_KEY_CONNECTOR + basToolsMetaDataTable.getTableName();
                String tableTags = basStorageService.selectTableTags(
                        basToolsMetaDataTable.getTenantId(),
                        basToolsMetaDataTable.getStorageId(),
                        basToolsMetaDataTable.getDatabaseName(),
                        basToolsMetaDataTable.getTableName()
                );

                if(StringUtils.isEmpty(tableTags)){
                    continue;
                }

                tableTagsMap.put(tableTagsKey, tableTags);
            }

            if(tableTagsMap.isEmpty()){
                log.debug("没有需要同步的元数据标签");
                return;
            }

            // 开始刷新 agent_tools_meta_database 的 table_tags 值
            tableTagsMap.forEach((key, value) -> {
                String[] keys = key.split(GROUP_KEY_CONNECTOR);
                String tenantId = keys[0];
                String storageId = keys[1];
                String databaseName = keys[2];
                String tableName = keys[3];

                // 更新 agent_tools_meta_database 表的 table_tags 字段
                toolsMetaDataTableService.updateTableTags(tenantId, storageId, databaseName, tableName, value);
            });

            log.info("元数据标签同步完成...");
        }catch (Exception e){
            log.error("元数据标签同步失败", e);
        }
    }
}